﻿#pragma once

#include <string>
#include <fstream>

#include <breaking/log/log_appender.h>
#include <breaking/time/date.h>

namespace breaking
{
	/**
	 * @brief 文件日志追加器
	 */
	struct log_event;
	class file_log_appender : public log_appender
	{
	public:
		explicit file_log_appender(const std::string& prefix, file_roll_type roll_type = file_roll_type::FILE_ROLL_DAY, size_t max_file_size = 0);
		virtual ~file_log_appender();

	protected:
		virtual bool do_open() override;
		virtual bool do_append(const log_event& event) override;
		virtual void do_close() override;

	protected:
		/**
		 * @brief 获取文件名
		 * @return
		 */
		std::string _get_file_name() const;

		/**
		 * @brief 根据时间检查是否需要重新打开文件
		 * @param now
		 * @return
		 */
		bool _check_reopen_by_date(const date& now) const;

		/**
		 * @brief 根据文件大小检查是否需要重新打开文件
		 * @return
		 */
		bool _check_reopen_by_size();

		/**
		 * @brief 确保目录存在, 如果不存在则创建
		 * @param file_path
		 */
		void _ensure_directory_exists(const std::string& file_path);

	protected:
		// 文件名前缀
		std::string					m_prefix;
		// 输出文件流
		std::ofstream				m_file_stream;
		// 打开文件的时间
		date						m_open_date;
		// 日志文件滚动标签,如果时间没变, 文件大小超过了最大值,则为ture
		bool						m_roll_flag;
	};
}